﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PMCSerialTransfer
{
    public abstract class APacket
    {
        public abstract bool Packet(byte[] Data);
        public abstract bool EndProcess(bool Ok);

        //public byte[] DataPacket { get; set; }
        public byte Command { get; set; }
 

        public bool CheckCRC(byte[] Data)
        {
            //UInt32 rslt;
            int length = Data[0];
            //byte[] buff = new byte[length-4];
            byte[] buff = new byte[length - 2];
            //byte[] crcBuff = new byte[4];
            byte[] crcBuff = new byte[2];
            bool checkCRC = true;

            for (int i = 0; i < buff.Length; i++)
                buff[i] = Data[i];

            //rslt = Crc32.Compute(buff);
            //crcBuff = BitConverter.GetBytes(rslt);
            Crc16 crc = new Crc16();
            crcBuff = crc.ComputeChecksumBytes(buff);
            ushort test = crc.ComputeChecksum(buff);
            //for (int i = 0; i < 4; i++)
            for (int i = 0; i < 2; i++)
            {
                if (BitConverter.IsLittleEndian)
                {
                    //if (Data[Data.Length - 4 + i] != crcBuff[3 - i] & checkCRC)
                    if (Data[Data.Length - 2 + i] != crcBuff[1 - i] & checkCRC)
                    {
                        checkCRC = false;
                    }
                }
                else
                {
                    //if (Data[Data.Length - 4 + i] != crcBuff[i] & checkCRC)
                    if (Data[Data.Length - 2 + i] != crcBuff[i] & checkCRC)
                    {
                        checkCRC = false;
                    }
                }
            }

            return checkCRC;
        }

        public bool Process(byte[] Data)
        {
            bool checkCRC = CheckCRC(Data);
            Globals.SendMsg = new byte[128];
            if (checkCRC)
            {
                //Globals.DataPacket = new byte[Data.Length - 6];
                //for (int i = 2; i < Data.Length - 4; i++)
                Globals.DataPacket = new byte[Data.Length - 4];
                for (int i = 2; i < Data.Length - 2; i++)
                    Globals.DataPacket[i - 2] = Data[i];
                Globals.AckResult = Globals.ACKType.E_ACK;
            }
            else
            {
                Globals.AckResult = Globals.ACKType.E_NACK;
            }

            return checkCRC;
        }

        //public void Create(byte command, byte[] Data)
        //{
        //    byte[] crcBuff = new byte[4];
        //    UInt32 rslt;

        //    Globals.DataPacket = new byte[Data.Length + 6];
        //    byte[] buff = new byte[Globals.DataPacket.Length - 4];
        //    Globals.DataPacket[0] = (byte)Globals.DataPacket.Length;
        //    Globals.DataPacket[1] = command;
        //    for (int i = 0; i < Data.Length; i++)
        //    {
        //        Globals.DataPacket[i + 2] = Data[i];
        //    }
        //    for (int i = 0; i < buff.Length; i++)
        //    {
        //        buff[i] = Globals.DataPacket[i];
        //    }
        //    rslt = Crc32.Compute(buff);
        //    crcBuff = BitConverter.GetBytes(rslt);

        //    for (int i = 0; i < 4; i++)
        //    {
        //        if (BitConverter.IsLittleEndian)
        //        {
        //            Globals.DataPacket[Globals.DataPacket.Length - 4 + i] = crcBuff[3 - i];
        //        }
        //        else
        //        {
        //            Globals.DataPacket[Globals.DataPacket.Length - 4 + i] = crcBuff[i];
        //        }
        //    }
        //}

        public void ACKPacket(Globals.ACKType E_Ack)
        {
            Globals.SendMsg = new byte[1];
            Globals.SendMsg[0] = (byte)E_Ack;
            Globals.Create((byte)CommFactory.Command.SndACK, Globals.SendMsg);
        }
    }
}
